package com.md.api.common.utils;

import com.md.api.common.config.BaseConfig;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;

/**
 * @author xdd
 * @create 2020-04-08 10:19
 **/
public class IpUtil {

    public final static List<String> qihooSpider = Arrays.asList("180.153.232", "180.153.234", "180.153.236", "180.163.220", "42.236.101", "42.236.102", "42.236.103", "42.236.10", "42.236.12", "42.236.13", "42.236.14", "42.236.15", "42.236.16", "42.236.17", "42.236.46", "42.236.48", "42.236.49", "42.236.50", "42.236.51", "42.236.52", "42.236.53", "42.236.54", "42.236.55", "42.236.99");

    public final static List<String> YisouSpider = Arrays.asList("106.11.152", "106.11.153", "106.11.154", "106.11.155", "106.11.156", "106.11.157", "106.11.158", "106.11.159", "42.120.160", "42.120.161", "42.156.136", "42.156.137", "42.156.138", "42.156.139", "42.156.254");

    /**
     * 字节跳动
     */
    public final static List<String> ByteSpider = Arrays.asList("110.249.201", "110.249.202", "111.225.147", "111.225.148", "111.225.149", "220.243.135", "220.243.136", "60.8.165", "60.8.9");


    /**
     * 获取真实IP
     *
     * @param request 请求体
     * @return 真实IP
     */
    public static String getRealIp(HttpServletRequest request) {
        String ipAddress = request.getHeader("x-forwarded-for");

        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknow".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                //根据网卡获取本机配置的IP地址
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress = inetAddress.getHostAddress();
            }
        }

        //对于通过多个代理的情况，第一个IP为客户端真实的IP地址，多个IP按照','分割
        if (null != ipAddress && ipAddress.length() > 15) {
            //"***.***.***.***".length() = 15
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }

        return ipAddress;
    }


    public static String isSpider(String ip) throws Exception {
        String result = execCmd("host " + ip, null);
        if (StringUtils.isEmpty(ip) && !isSpiderUa(result)) {
            for (String s : qihooSpider) {
                if (ip.startsWith(s)) {
                    return "so.com";
                }
            }
            for (String s : YisouSpider) {
                if (ip.startsWith(s)) {
                    return "sm.cn";
                }
            }
            for (String s : ByteSpider) {
                if (ip.startsWith(s)) {
                    return "bytedance.com";
                }
            }
        }
        return result;
    }

    /**
     * 执行系统命令, 返回执行结果
     *
     * @param cmd 需要执行的命令
     * @param dir 执行命令的子进程的工作目录, null 表示和当前主进程工作目录相同
     */
    public static String execCmd(String cmd, File dir) throws Exception {
        StringBuilder result = new StringBuilder();

        Process process = null;
        BufferedReader bufrIn = null;
        BufferedReader bufrError = null;

        try {
            // 执行命令, 返回一个子进程对象（命令在子进程中执行）
            process = Runtime.getRuntime().exec(cmd, null, dir);

            // 方法阻塞, 等待命令执行完成（成功会返回0）
            process.waitFor();

            // 获取命令执行结果, 有两个结果: 正常的输出 和 错误的输出（PS: 子进程的输出就是主进程的输入）
            bufrIn = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
            bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));

            // 读取输出
            String line = null;
            while ((line = bufrIn.readLine()) != null) {
                result.append(line).append('n');
            }
            while ((line = bufrError.readLine()) != null) {
                result.append(line).append('n');
            }

        } finally {
            closeStream(bufrIn);
            closeStream(bufrError);

            // 销毁子进程
            if (process != null) {
                process.destroy();
            }
        }

        // 返回执行结果
        return result.toString();
    }


    private static void closeStream(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (Exception e) {
                // nothing
            }
        }
    }


    public static boolean isSpiderUa(String hostname) {
        List<String> spiders = BaseConfig.SPIDER;
        for (String spider : spiders) {
            if (hostname.toLowerCase().contains(spider)) {
                return true;
            }
        }
        return false;
    }


    public static String getAddressByIP() {
        try {
            String strIP = "183.67.61.22";
            URL url = new URL("http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=" + strIP);
            URLConnection conn = url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
            String line = null;
            StringBuffer result = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            reader.close();
            strIP = result.substring(result.indexOf("该IP所在地为："));
            strIP = strIP.substring(strIP.indexOf("：") + 1);
            String province = strIP.substring(6, strIP.indexOf("省"));
            String city = strIP.substring(strIP.indexOf("省") + 1, strIP.indexOf("市"));
            return province+city;
        } catch (IOException e) {
            return "读取失败";
        }
     }

     //获取服务器ip
    public static String getLocalIP() {
        String ret = "";
        try {
            InetAddress address = InetAddress.getLocalHost();
            ret = address.getHostAddress();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return ret;
    }

    public static void main(String[] args) {
        String localIP = getLocalIP();
        System.out.println(localIP);
    }
}

